package mcontext

import (
	"context"
	"os"

	"github.com/google/uuid"
	"go.uber.org/zap/zapcore"

	"go.uber.org/zap"
)

type correlationIdType int

const (
	requestIdKey correlationIdType = iota
)

var logger *zap.Logger

func init() {
	// 初始化logger
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.TimeKey = "time"
	core := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		zapcore.AddSync(os.Stdout),
		zap.NewAtomicLevelAt(zap.InfoLevel),
	)
	logger = zap.New(core, zap.AddStacktrace(zapcore.FatalLevel), zap.AddCaller())
}

// WithRqId returns a context which knows its request ID
func WithRqId(ctx context.Context, rqId string) context.Context {
	return context.WithValue(ctx, requestIdKey, rqId)
}

func GetRqId(ctx context.Context) interface{} {
	return ctx.Value(requestIdKey)
}

// Logger returns a zap logger with as much context as possible
func Logger(ctx context.Context) *zap.Logger {
	newLogger := logger
	if ctx != nil {
		if ctxRqId, ok := ctx.Value(requestIdKey).(string); ok {
			newLogger = newLogger.With(zap.String("rqId", ctxRqId))
		}
	}
	return newLogger
}

func GenContextWithRqId() (ctx context.Context) {
	ctx = context.Background()
	requestId := uuid.New().String()
	ctx = WithRqId(ctx, requestId)
	return
}
